package com.example.qqviewspringboot.service;

import com.example.qqviewspringboot.data.Message;
import com.example.qqviewspringboot.data.User;
import com.example.qqviewspringboot.repository.MessageRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private UserService userService;  // 用于查询好友名称

    @Autowired
    private MessageRepository messageRepository;

    @Autowired
    private MessagePushService messagePushService;  // 新增 MessagePushService 依赖

    @Autowired
    public MessageServiceImpl(MessageRepository messageRepository) {
        this.messageRepository = messageRepository;
    }

    /**
     * 保存消息并通知接收者（包括媒体）
     *
     * @param senderId    发送者ID
     * @param recipientId 接收者ID
     * @param content     消息内容
     * @param mediaType   媒体类型
     * @param mediaUrl    媒体URL
     * @return 保存的消息
     */
    @Override
    @Transactional
    public Message saveAndNotifyMessage(Long senderId, Long recipientId, String content, String mediaType, String mediaUrl) {
        // 参数校验
        if (senderId == null || recipientId == null ||
                (content == null || content.trim().isEmpty()) && (mediaUrl == null || mediaUrl.trim().isEmpty())) {
            throw new IllegalArgumentException("Sender ID and recipient ID must not be null. Content or media must be provided.");
        }

        // 获取发送者和接收者
        User sender = userService.getUserById(senderId);
        User recipient = userService.getUserById(recipientId);

        if (sender == null || recipient == null) {
            throw new IllegalArgumentException("Sender or recipient does not exist.");
        }

        // 创建消息对象
        Message message = new Message();
        message.setSender(sender);
        message.setRecipient(recipient);
        message.setContent(content != null ? content : "");
        message.setTimestamp(LocalDateTime.now());
        message.setReadStatus(Message.ReadStatus.UNREAD);

        // 设置媒体信息
        if (mediaType != null && mediaUrl != null) {
            message.setMediaType(mediaType);
            message.setMediaUrl(mediaUrl);
        }

        // 保存消息到数据库
        Message savedMessage = messageRepository.save(message);

        // 推送消息
        boolean isPushed = messagePushService.pushMessageIfOnline(recipientId, content, mediaType, mediaUrl);

        // 根据推送结果更新消息状态
        if (isPushed) {
            savedMessage.setReadStatus(Message.ReadStatus.DELIVERED);
        } else {
            savedMessage.setReadStatus(Message.ReadStatus.UNREAD);
        }
        messageRepository.save(savedMessage);

        return savedMessage;
    }

    /**
     * 保存消息并通知接收者（如果接收者在线，则推送消息；否则，保持消息状态为未推送）
     *
     * @param senderId    发送者ID
     * @param recipientId 接收者ID
     * @param content     消息内容
     * @return 保存的消息
     */
    @Override
    public Message saveAndNotifyMessage(Long senderId, Long recipientId, String content) {
        // 参数校验
        if (senderId == null || recipientId == null || content == null || content.trim().isEmpty()) {
            throw new IllegalArgumentException("Sender ID, recipient ID, and content must not be null or empty.");
        }

        // 从数据库获取完整的 User 对象
        User sender = userService.getUserById(senderId);
        User recipient = userService.getUserById(recipientId);

        // 创建消息对象
        Message message = new Message();
        message.setSender(sender);
        message.setRecipient(recipient);
        message.setContent(content);
        message.setTimestamp(LocalDateTime.now());
        message.setReadStatus(Message.ReadStatus.UNREAD);  // 默认未读

        // 保存消息到数据库
        Message savedMessage = messageRepository.save(message);

        // 使用 MessagePushService 判断是否推送消息
        boolean isPushed = messagePushService.pushMessageIfOnline(recipientId, content);  // 推送消息

        // 如果推送成功，标记为已推送
        if (isPushed) {
            savedMessage.setReadStatus(Message.ReadStatus.DELIVERED);
        } else {
            savedMessage.setReadStatus(Message.ReadStatus.UNREAD);
        }
        messageRepository.save(savedMessage);

        return savedMessage;
    }

    /**
     * 获取指定用户与好友之间的所有消息
     *
     * @param userId   用户ID
     * @param friendId 好友ID
     * @return 消息列表
     */
    @Override
    public List<Message> getConversation(Long userId, Long friendId) {
        // 获取用户和好友之间的所有消息
        return messageRepository.findByUsers(userId, friendId);
    }

    /**
     * 获取未读消息
     *
     * @param userId 用户ID
     * @return 未读消息列表
     */
    @Override
    public List<Message> getUnreadMessages(Long userId) {
        return messageRepository.findUnreadMessagesForUser(userId);
    }

    /**
     * 批量标记消息为已读
     *
     * @param messageIds 消息ID列表
     */
    @Override
    public void markMessagesAsRead(List<Long> messageIds) {
        // 校验消息ID是否有效
        if (messageIds == null || messageIds.isEmpty()) {
            throw new IllegalArgumentException("Message IDs cannot be null or empty.");
        }

        List<Message> messages = messageRepository.findAllById(messageIds);
        if (messages == null || messages.isEmpty()) {
            throw new IllegalArgumentException("No messages found for the given IDs.");
        }

        // 批量标记为已读
        for (Message message : messages) {
            if (message != null) {
                message.setReadStatus(Message.ReadStatus.READ);  // 设置为已读
            }
        }

        // 批量保存更新后的消息
        messageRepository.saveAll(messages);
    }

    /**
     * 获取未推送的消息
     *
     * @param recipientId 接收者ID
     * @return 未推送的消息列表
     */
    @Override
    public List<Message> getPendingMessages(Long recipientId) {
        // 查询指定用户（recipientId）未读的消息
        return messageRepository.findByRecipientIdAndReadStatus(recipientId, Message.ReadStatus.UNREAD);
    }

    /**
     * 保存消息方法
     *
     * @param senderId    发送者ID
     * @param recipientId 接收者ID
     * @param content     消息内容
     * @return 保存的消息
     */
    @Override
    public Message saveMessage(Long senderId, Long recipientId, String content) {
        // 参数校验
        if (senderId == null || recipientId == null || content == null || content.trim().isEmpty()) {
            throw new IllegalArgumentException("Sender ID, recipient ID, and content must not be null or empty.");
        }

        // 创建消息对象并填充字段
        Message message = new Message();
        message.setSender(userService.getUserById(senderId));
        message.setRecipient(userService.getUserById(recipientId));
        message.setContent(content);
        message.setTimestamp(LocalDateTime.now());  // 设置时间戳为当前时间
        message.setReadStatus(Message.ReadStatus.UNREAD);  // 设置为未读状态

        // 保存消息到数据库
        return messageRepository.save(message);  // 将消息对象保存到数据库
    }

    /**
     * 获取指定用户的所有对话
     *
     * @param userId 用户ID
     * @return 包含对话信息的列表，每个对话包括对方用户ID、最新消息内容、时间戳、未读状态等
     */
    @Override
    public List<Object[]> getAllConversations(Long userId) {
        // 查询所有与用户相关的消息，按时间降序排列
        List<Message> messages = messageRepository.findBySenderIdOrRecipientIdOrderByTimestampDesc(userId, userId);

        // 用于存储每个对话的信息（包括对方用户ID、最新消息等）
        List<Object[]> conversations = new ArrayList<>();

        // 用于存储已经处理过的对话，避免重复添加
        Map<Long, Object[]> conversationMap = new HashMap<>();

        for (Message message : messages) {
            // 计算该消息属于哪个对话
            Long otherUserId = message.getSender().getId().equals(userId) ? message.getRecipient().getId() : message.getSender().getId();

            // 如果该对话信息已经存在，则不重复添加，更新最新的消息
            if (!conversationMap.containsKey(otherUserId)) {
                // 查询好友的名称
                String friendName = userService.getUserNameById(otherUserId);

                // 获取对方用户的头像URI
                String avatarUri = null;

                // 确保返回对方用户的头像URI
                if (message.getSender().getId().equals(userId)) {
                    // 当前用户是发送者，获取接收者的头像
                    avatarUri = message.getRecipient().getAvatarUri();
                } else {
                    // 当前用户是接收者，获取发送者的头像
                    avatarUri = message.getSender().getAvatarUri();
                }

                // 存储对话的详细信息，包括好友名称和头像URI
                conversationMap.put(otherUserId, new Object[]{
                        otherUserId,                // 对方用户ID
                        message.getContent(),       // 最新消息内容
                        message.getTimestamp(),     // 时间戳
                        message.getReadStatus(),    // 消息的未读状态
                        friendName,                 // 好友名称
                        avatarUri                   // 好友头像URI
                });
            }
        }

        // 将所有对话信息加入列表
        conversations.addAll(conversationMap.values());

        return conversations;
    }


    /**
     * 更新消息状态
     */
    @Override
    public void updateMessageStatus(Message message) {
        if (message == null || message.getId() == null) {
            throw new IllegalArgumentException("Message or Message ID cannot be null.");
        }
        messageRepository.save(message);
    }
}
